﻿namespace Kwan.Cache
{
    using Kwan;
    using System;
    using System.Collections.Generic;
    using System.Threading;
    using System.Web;
    using System.Web.Caching;

    public class CacheManage
    {
        private int x12713c3af463038a;
        private readonly HttpContext H = new HttpContext(new HttpRequest("Null.File", "http://www.yj-star.com", string.Empty), new HttpResponse(null));
        private int x5bfd2bd711f4f4a4;
        private Dictionary<string, CacheDependencyInfo> cacheState = new Dictionary<string, CacheDependencyInfo>();
        private Cache theCache;
        private DateTime cacheTime;

        private CacheManage()
        {
            this.theCache = this.H.Cache;
            new Thread(new ThreadStart(this.xa5231ec1f6e403b2)) { IsBackground = true }.Start();
            this.cacheTime = DateTime.Now.AddMinutes(5.0);
        }


        public int Count
        {
            get { return theCache == null ? 0 : theCache.Count; }
        }

        private class Shell
        {
            internal static readonly CacheManage instance = new CacheManage();
        }

        public static CacheManage Instance
        {
            get { return Shell.instance; }
        }

        public void Add(string key, object value)
        {
            this.Add(key, value, null, 0.0);
        }

        public void Add(string key, object value, string filePath)
        {
            this.Add(key, value, filePath, 0.0);
        }

        public void Add(string key, object value, string filePath, double cacheTimeMinutes)
        {
            if (this.Contains(key))
            {
                this.Remove(key);
            }
            this.Insert(key, value, filePath, cacheTimeMinutes);
        }

        public void Clear()
        {
            try
            {
                foreach (KeyValuePair<string, CacheDependencyInfo> pair in this.cacheState)
                {
                    this.theCache.Remove(pair.Key);
                }
                this.cacheState.Clear();
            }
            catch
            {
                this.x5bfd2bd711f4f4a4++;
            }
        }

        public bool Contains(string key)
        {
            if (this.theCache[key] != null)
            {
                return true;
            }
            if (this.cacheState.ContainsKey(key))
            {
                try
                {
                    this.cacheState.Remove(key);
                }
                catch
                {
                    this.x5bfd2bd711f4f4a4++;
                }
            }
            return false;
        }

        public object Get(string key)
        {
            try
            {
                CacheDependencyInfo local1 = this.cacheState[key];
                local1.CallCount++;
            }
            catch
            {
                this.x5bfd2bd711f4f4a4++;
            }
            return this.theCache[key];
        }

        public bool GetHasChanged(string key)
        {
            if (this.cacheState.ContainsKey(key) && this.Contains(key))
            {
                CacheDependencyInfo info = this.cacheState[key];
                if (info != null)
                {
                    return (!info.IsChanged && info.SetChange);
                }
            }
            else if (this.Contains("Kwan.Cache:Temp_" + key))
            {
                return (bool) this.theCache.Get("Kwan.Cache:Temp_" + key);
            }
            return false;
        }

        public void Remove(string key)
        {
            if (this.Contains(key))
            {
                try
                {
                    this.theCache.Remove(key);
                    this.cacheState.Remove(key);
                }
                catch
                {
                    this.x5bfd2bd711f4f4a4++;
                }
            }
        }

        public void Set(string key, object value)
        {
            if (this.Contains(key))
            {
                this.theCache[key] = value;
            }
            else
            {
                this.Insert(key, value, null, 0.0);
            }
        }

        public void SetChange(string key, bool change)
        {
            if (this.cacheState.ContainsKey(key) && this.Contains(key))
            {
                CacheDependencyInfo info = this.cacheState[key];
                if (info != null)
                {
                    info.UserSetChange(change);
                }
            }
            else
            {
                this.Add("Kwan.Cache:Temp_" + key, change, null, 0.1);
            }
        }

        public void Update(string key, object value)
        {
            if (this.Contains(key))
            {
                this.theCache[key] = value;
            }
        }

        private void xa5231ec1f6e403b2()
        {
            List<string> list = new List<string>();
        Label_0006:
            try
            {
                Thread.Sleep(0x493e0);
                if (this.theCache.Count != this.cacheState.Count)
                {
                    foreach (KeyValuePair<string, CacheDependencyInfo> pair in this.cacheState)
                    {
                        if (((pair.Value.CreaeTime.AddMinutes(4.0) >= DateTime.Now) || (pair.Value.CallCount >= 2)) && (pair.Value.CreaeTime.AddMinutes(pair.Value.CacheMinutes) >= DateTime.Now))
                        {
                            continue;
                        }
                        if (!list.Contains(pair.Key))
                        {
                            list.Add(pair.Key);
                        }
                    }
                    foreach (string str in list)
                    {
                        this.Remove(str);
                    }
                    this.x12713c3af463038a = list.Count;
                    list.Clear();
                }
                this.cacheTime = DateTime.Now.AddMinutes(5.0);
                goto Label_0006;
            }
            catch
            {
                Thread.Sleep(TimeSpan.FromHours(1.0));
                goto Label_0006;
            }
        }

        private void Insert(string key, object value, string filePath, double cacheTimeMinutes)
        {
            CacheDependency dependencies = null;
            if (!string.IsNullOrEmpty(filePath))
            {
                dependencies = new CacheDependency(filePath);
            }
            double defaultMinutes = cacheTimeMinutes;
            if (cacheTimeMinutes == 0.0)
            {
                defaultMinutes = 30.0;
            }
            this.theCache.Insert(key, (value == null) ? string.Empty : value, dependencies, DateTime.Now.AddMinutes(defaultMinutes), TimeSpan.Zero, CacheItemPriority.Normal, null);
            CacheDependencyInfo info = new CacheDependencyInfo(dependencies, defaultMinutes);
            if (this.cacheState.ContainsKey(key))
            {
                this.cacheState[key] = info;
            }
            else
            {
                try
                {
                    this.cacheState.Add(key, info);
                }
                catch
                {
                }
            }
        }

        public Dictionary<string, CacheDependencyInfo> CacheInfo
        {
            get
            {
                return this.cacheState;
            }
        }

        public long RemainMemoryBytes
        {
            get
            {
                return this.theCache.EffectivePrivateBytesLimit;
            }
        }

        public long RemainMemoryPercentage
        {
            get
            {
                return this.theCache.EffectivePercentagePhysicalMemoryLimit;
            }
        }

        public string WorkInfo
        {
            get
            {
                return string.Format("try catch error:{0}(times)--clear count:{1}--next clear work time at:{2}", this.x5bfd2bd711f4f4a4, this.x12713c3af463038a, this.cacheTime);
            }
        }

    }
}

